package com.googlecode.sparda.commons.performance;

import com.googlecode.sparda.commons.constant.TimeConstant;

/**
 * Class that represent a {@link CachedValue} whit a constant validity time.
 * The typical use of a {@link TimedCachedValue} occurs when an onerous computation must be done (we can't),
 * but we want the value cached to be invalidated after a precisely defined time intervals.
 * This class expire when the {@link #getExpirePeriod()} is past.
 * If you need an ultra efficient {@link #getValue()} performance see {@link ThreadTimedCachedValue}.
 * @author Fabio Grucci (<i>alias</i> <b>Phoenix</b>)
 * @version 1.0
 * @since 1.0
 * @see ThreadTimedCachedValue
 */
public abstract class TimedCachedValue<T> extends CachedValue<T> {

	private long expirePeriod;
	
	/**
	 * Build a {@link TimedChachedValue} with a period of validity. 
	 * @param period The period of validity of the value in milliseconds.
	 */
	public TimedCachedValue(long expirePeriod) {
		this.expirePeriod = expirePeriod;
	}
	
	/**
	 * Build a {@link TimedChachedValue} with a period of validity 
	 * of one minute and an initial value.
	 * @param initialValue The starting value for the variable
	 */
	public TimedCachedValue(T initialValue) {
		this(initialValue, TimeConstant.ONE_MINUTE);
	}
	/**
	 * Build a {@link TimedChachedValue} with a period of validity
	 * and an initial value.
	 * @param initialValue The starting value for the variable
	 * @param period The period of validity of the value in milliseconds.
	 */
	public TimedCachedValue(T initialValue, long expirePeriod) {
		this.expirePeriod = expirePeriod;
		this.setValue(initialValue);
	}
	/*
	 * (non-Javadoc)
	 * @see com.googlecode.sparda.commons.performance.CachedValue#isExpired()
	 */
	@Override
	public boolean isExpired() {
		if(!this.expired && isOutOfExpirePeriod())
			this.expireCache();
		return super.isExpired();
	}
	/**
	 * Check the current cached value is expired.
	 * @return <code>true</code> if expired, <code>false</code> otherwise
	 */
	private boolean isOutOfExpirePeriod() {
		return System.currentTimeMillis() > this.getLastUpdateTime() + this.expirePeriod;
	}
	
	/**
	 * Method that change the validity time of the {@link CachedValue}.
	 * @param expirePeriod The validity time of the {@link CachedValue} in milliseconds
	 */
	public void setExpirePeriod(long expirePeriod) {
		this.expirePeriod = expirePeriod;
	}
	
	/**
	 * Method that return the validity time of the variable.
	 * @return The validity time in milliseconds
	 */
	public long getExpirePeriod() {
		return this.expirePeriod;
	}
	
	
}
